package com.windowes.weichang.service;

import com.google.gson.Gson;
import com.windowes.weichang.common.ServerResponse;
import com.windowes.weichang.component.redis.RedisService;
import com.windowes.weichang.dao.WDistrictMapper;
import com.windowes.weichang.dto.WDistrictDto;
import com.windowes.weichang.pojo.WDistrict;
import com.windowes.weichang.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/***
 *
 * @author: yangqing
 * @email: qing.yang@bangdao-tech.com
 * @createTime: 2018/5/25 下午5:45
 * @description:
 *
 **/
@Service
@Slf4j
public class DistrictService {

    @Autowired
    private WDistrictMapper districtMapper;

    @Autowired
    private RedisService redisService;

    /**
     * 查询单个地区
     *
     * @param id
     * @return
     */
    public ServerResponse getItem(Integer id) {
        if (id == null) {
            return ServerResponse.createByErrorMessage("请提交id!");
        }
        WDistrict wDistrict = districtMapper.selectByPrimaryKey(id);
        if (wDistrict == null) {
            return ServerResponse.createByErrorMessage("该地区不存在!");
        }
        return ServerResponse.createBySuccess("获取成功!", wDistrict);
    }

    /**
     * 获取递归地区树
     *
     * @param parentId
     * @return
     */
    public ServerResponse getTree(Integer parentId) {
        List<WDistrictDto> memoryDistrict = redisService.getDistrict(parentId);
        if (memoryDistrict != null && !memoryDistrict.isEmpty()) {
            return ServerResponse.createBySuccess("获取成功!", memoryDistrict);
        }
        List<WDistrict> districts = districtMapper.selectAll();
        memoryDistrict = new ArrayList<>();
        for (WDistrict district : districts) {
            WDistrictDto target = new WDistrictDto();
            BeanUtils.copyProperties(district, target);
            memoryDistrict.add(target);
        }
        List<WDistrictDto> dstList = buildTree(parentId, memoryDistrict);
        if (dstList.isEmpty()) {
            return ServerResponse.createByErrorMessage("未查到地区相关数据!");
        }
        redisService.setDistrict(parentId, dstList);
        return ServerResponse.createBySuccess("获取成功!", dstList);
    }

    private List<WDistrictDto> buildTree(Integer parentId, List<WDistrictDto> memoryDistrict) {
        List<WDistrictDto> children = new ArrayList<>();
        for (WDistrictDto district : memoryDistrict) {
            if (district.getParentId().compareTo(parentId) == 0) {
                district.setChildren(buildTree(district.getId(), memoryDistrict));
                children.add(district);
            }
        }
        return children;
    }


    /**
     * 获取地区及其递归子集
     * 【效率较低,弃用】
     *
     * @return
     * @deprecated
     */
    public ServerResponse getItemWithChildren(Integer id) {
        if (id == null) {
            return ServerResponse.createByErrorMessage("请提交id!");
        }
        List<WDistrictDto> memoryDistrict = redisService.getDistrict(id);
        if (memoryDistrict != null && !memoryDistrict.isEmpty()) {
            return ServerResponse.createBySuccess("获取成功!", memoryDistrict);
        }

        List<WDistrictDto> dstList = buildTree(id);
        if (dstList.isEmpty()) {
            return ServerResponse.createByErrorMessage("未查到地区相关数据!");
        }
        redisService.setDistrict(id, dstList);
        return ServerResponse.createBySuccess("获取成功!", dstList);
    }

    /**
     * 获取地区及其递归子集
     *
     * @param parentId
     * @return
     * @deprecated
     */
    private List<WDistrictDto> buildTree(Integer parentId) {
        List<WDistrict> districts = districtMapper.selectByParentId(parentId);
        List<WDistrictDto> wDistrictDtos = new ArrayList<>();
        for (int i = 0; districts != null && i < districts.size(); i++) {
            WDistrict district = districts.get(i);
            WDistrictDto dto = new WDistrictDto();
            BeanUtils.copyProperties(district, dto);
            dto.setChildren(buildTree(dto.getId()));
            wDistrictDtos.add(dto);
        }
        return wDistrictDtos;
    }

    /**
     * 初始化导入地区
     */
    public void init() {
        new Thread(() -> {
            List<WDistrict> districts = districtMapper.selectAll();
            if (districts.isEmpty()) {
                log.info("======开始初始化地区数据=======");
                String toString = FileUtil.readToString("pcas-code.json");
                WDistrictDto[] wDistrictDtos = new Gson().fromJson(toString, WDistrictDto[].class);
                insertRecursion(Arrays.asList(wDistrictDtos), 0, -1);
                log.info("======初始化地区数据结束=======");
            } else {
                log.info("======已存在地区数据,不需初始化地区数据=======");
            }
        }).start();
    }

    /**
     * 递归插入地区
     *
     * @param children
     * @param parentId
     * @param level
     */
    private void insertRecursion(List<WDistrictDto> children, int parentId, int level) {
        level++;
        for (int i = 0; children != null && i < children.size(); i++) {
            WDistrictDto wDistrictDto = children.get(i);
            WDistrict wDistrict = new WDistrict();
            BeanUtils.copyProperties(wDistrictDto, wDistrict);
            wDistrict.setParentId(parentId);
            wDistrict.setLevel(level);
            districtMapper.insertSelective(wDistrict);
            insertRecursion(wDistrictDto.getChildren(), wDistrict.getId(), level);
        }
    }

    /**
     * 获取地区下直接子集
     *
     * @param id
     * @return
     */
    public ServerResponse itemWithSubLevel(Integer id) {
        if (id == null) {
            return ServerResponse.createByErrorMessage("请提交id!");
        }
        WDistrict wDistrict = districtMapper.selectByPrimaryKey(id);
        if (wDistrict == null) {
            return ServerResponse.createByErrorMessage("该地区不存在!");
        }
        WDistrictDto dto = new WDistrictDto();
        BeanUtils.copyProperties(wDistrict, dto);
        List<WDistrict> districts = districtMapper.selectByParentId(dto.getId());
        List<WDistrictDto> districtDtos = new ArrayList<>();
        for (WDistrict item : districts) {
            WDistrictDto itemDto = new WDistrictDto();
            BeanUtils.copyProperties(item, itemDto);
            districtDtos.add(itemDto);
        }
        dto.setChildren(districtDtos);
        return ServerResponse.createBySuccess("获取成功!", dto);
    }

    public ServerResponse subList(Integer id) {
        List<WDistrict> districts = districtMapper.selectByParentId(id);
        List<WDistrictDto> districtDtos = new ArrayList<>();
        for (WDistrict item : districts) {
            WDistrictDto itemDto = new WDistrictDto();
            BeanUtils.copyProperties(item, itemDto);
            districtDtos.add(itemDto);
        }
        return ServerResponse.createBySuccess("获取成功!", districtDtos);
    }

    /**
     * 获取标准地址
     *
     * @return
     */
    public ServerResponse<String> getStandardAddress(Integer provinceId,
                                                     Integer cityId,
                                                     Integer areaId,
                                                     Integer streetId) {
        WDistrict district = districtMapper.selectByPrimaryKey(provinceId);
        WDistrict district1 = districtMapper.selectByPrimaryKey(cityId);
        WDistrict district2 = districtMapper.selectByPrimaryKey(areaId);
        WDistrict district3 = districtMapper.selectByPrimaryKey(streetId);
        return ServerResponse.createBySuccess(district.getName() + district1.getName() + district2.getName() + district3.getName());

    }


    public ServerResponse updateDistrict() {
        List<WDistrict> districts = districtMapper.selectByLevel(1);
        //更新目录
        for (WDistrict item : districts) {
            if ("市辖区".equals(item.getName())) {
                WDistrict parent = districtMapper.selectByPrimaryKey(item.getParentId());
                WDistrict it = new WDistrict();
                it.setId(item.getId());
                it.setName(parent.getName());
                districtMapper.updateByPrimaryKeySelective(it);
            }
        }
        return ServerResponse.createBySuccess();
    }

    public ServerResponse subListLevel1() {
        List<WDistrict> districts = districtMapper.selectByLevel(1);
        return ServerResponse.createBySuccess(districts);
    }
}
